1
'--------------------------------------------------------------------------
3 ' Copyright (c) Microsoft Corporation. All rights reserved.
5 ' File: ParallelGrep.vb
7 '--------------------------------------------------------------------------
11 Imports System
.Text
.RegularExpressions
12 Imports System
.Threading
14 Friend Class ParallelGrep
15 Shared
Sub Main(ByVal args() As String)
16 ' Parse command-line switches
17 Dim recursive
= args
.Contains("/s")
18 Dim ignoreCase
= args
.Contains("/i")
20 ' Get the regex and file wildcards from the command-line
21 Dim nonSwitches
= From arg
In args
22 Where arg
.FirstOrDefault() <> "/"c
24 Dim regexString
= nonSwitches
.FirstOrDefault()
25 Dim wildcards
= nonSwitches
.Skip(1)
27 ' Create thread-local Regex instances, to prevent contention on Regex's internal lock
28 Dim regex
= New ThreadLocal(Of Regex
)(Function() New Regex(regexString
, RegexOptions
.Compiled
Or
29 (If(ignoreCase
, RegexOptions
.IgnoreCase
, RegexOptions
.None
))))
31 ' Get the list of files to be examined
32 Dim files
= From wc
In wildcards
33 Let dirName
= Path
.GetDirectoryName(wc
)
34 Let fileName
= Path
.GetFileName(wc
)
35 From file
In Directory
.EnumerateFiles(If(String.IsNullOrWhiteSpace(dirName
), ".", dirName
),
36 If(String.IsNullOrWhiteSpace(fileName
), "*.*", fileName
),
37 If(recursive
, SearchOption
.AllDirectories
, SearchOption
.TopDirectoryOnly
))
41 ' Traverse the specified files in parallel, and run each line through the Regex, collecting line number info
42 ' for each match (the Zip call counts the lines in each file)
44 Dim matches
= From file
In files
.AsParallel().AsOrdered().WithMergeOptions(ParallelMergeOptions
.NotBuffered
)
45 From line
In System
.IO
.File
.ReadLines(file
).
46 Zip(Enumerable
.Range(1, Integer.MaxValue
), Function(s
, i
) New With {Key
.Num
= i
, Key
.Text
= s
, Key
.File
= file
})
47 Where regex
.Value
.IsMatch(line
.Text
)
49 For Each line
In matches
50 Console
.WriteLine("{0}:{1} {2}", line
.File
, line
.Num
, line
.Text
)
52 Catch ae
As AggregateException
54 Console
.WriteLine(e
.Message
)